﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Experimental.Rendering.RenderGraphModule;
using UnityEngine.Rendering;

namespace BPipeline.Runtime.RenderPass
{
    public class GBufferPass
    {
        static ShaderTagId pass =  new ShaderTagId(nameof(GBufferPass));
        public class PresentPassData
        {
            public TextureHandle depthBuffer;
            public TextureHandle gBufferPosWR;
            public TextureHandle gBufferNorWM;
            public TextureHandle gBufferAlbedo;
        }
        static public PresentPassData  Excute(RenderGraph renderGraph,Camera camera)
        {
            using (var builder = renderGraph.AddRenderPass<PresentPassData>(nameof(GBufferPass), out var gBufferPassData))
            {
                gBufferPassData.gBufferPosWR = renderGraph.CreateTexture(new TextureDesc(camera.pixelWidth,camera.pixelHeight)
                {
                    colorFormat = UnityEngine.Experimental.Rendering.GraphicsFormat.R32G32B32A32_SFloat,
                    name = "gBufferPosWR",
                    clearBuffer = true,
                    clearColor = Color.clear
                });
                gBufferPassData.gBufferNorWM = renderGraph.CreateTexture(new TextureDesc(camera.pixelWidth, camera.pixelHeight)
                {
                    colorFormat = UnityEngine.Experimental.Rendering.GraphicsFormat.R32G32B32A32_SFloat,
                    name = "gBufferNorWM",
                    clearBuffer = true,
                    clearColor = Color.clear
                });
                gBufferPassData.gBufferAlbedo = renderGraph.CreateTexture(new TextureDesc(camera.pixelWidth, camera.pixelHeight)
                {
                    colorFormat = UnityEngine.Experimental.Rendering.GraphicsFormat.R32G32B32A32_SFloat,
                    name = "gBufferAlbedo",
                    clearBuffer = true,
                    clearColor = Color.clear
                });
                gBufferPassData.depthBuffer = renderGraph.CreateTexture(new TextureDesc(camera.pixelWidth, camera.pixelHeight)
                {
                    depthBufferBits = DepthBits.Depth32,
                    name = "depthBuffer",
                    clearBuffer = true,
                });

                builder.UseColorBuffer(gBufferPassData.gBufferPosWR, 0);
                builder.UseColorBuffer(gBufferPassData.gBufferNorWM, 1);
                builder.UseColorBuffer(gBufferPassData.gBufferAlbedo, 2);
                builder.UseDepthBuffer(gBufferPassData.depthBuffer, DepthAccess.ReadWrite);


                builder.SetRenderFunc(
                    (PresentPassData gBufferPassData, RenderGraphContext ctx) =>
                    {
                        ctx.cmd.SetViewProjectionMatrices(camera.worldToCameraMatrix, camera.projectionMatrix);
                        ctx.renderContext.ExecuteCommandBuffer(ctx.cmd);
                        ctx.cmd.Clear();
                        camera.TryGetCullingParameters(out var cullingParameters);
                        var cullResults = ctx.renderContext.Cull(ref cullingParameters);
                        SortingSettings sortingSettings = new SortingSettings(camera);
                        FilteringSettings filteringSettings = new FilteringSettings(RenderQueueRange.opaque);
                        DrawingSettings drawingSettings = new DrawingSettings(pass, sortingSettings);

                        ctx.renderContext.DrawRenderers(cullResults, ref drawingSettings, ref filteringSettings);

                    });

                return gBufferPassData;
            }
        
    }
    }
}
